﻿using System;
using Microsoft.Xna.Framework;

namespace Phoenix.Xna.Framework.Components
{
    public abstract class Component : EngineComponent, IComponent
    {
        private int _updateOrder;

        public Component()
            : base()
        {
            Enabled = true;
            SubComponents = new ComponentCollection();
        }

        public Component(string id)
            : base(id)
        {
            Enabled = true;
            SubComponents = new ComponentCollection();
        }

        public override bool Equals(object obj)
        {
            if (System.Object.ReferenceEquals(this, obj))
            {
                return true;
            }

            if (obj != null && obj is IComponent)
            {
                IComponent component = obj as IComponent;
                return string.Compare(component.ID, ID, true) == 0;
            }

            return false;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public static bool operator ==(Component left, Component right)
        {
            if (System.Object.ReferenceEquals(left, right))
            {
                return true;
            }

            if (!System.Object.ReferenceEquals(left, null))
            {
                if (System.Object.ReferenceEquals(right, null))
                {
                    return false;
                }
                else
                {
                    return left.Equals(right);
                }
            }

            return false;
        }

        public static bool operator !=(Component left, Component right)
        {
            return (left == right) ? false : true;
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!IsDisposed && disposing)
            {
                SubComponents.Dispose();
                IsDisposed = true;
            }
        }

        #region IComponent Members

        public event EventHandler<UpdateOrderChangedEventArgs> UpdateOrderChanged;

        public bool Enabled { get; set; }
        public bool IsInitialized { get; protected set; }
        public ComponentCollection SubComponents { get; set; }
        public int UpdateOrder
        {
            get { return _updateOrder; }
            set
            {
                if (_updateOrder != value)
                {
                    int oldValue = _updateOrder;
                    _updateOrder = value;
                    EventHandler<UpdateOrderChangedEventArgs> handler = UpdateOrderChanged;

                    if (handler != null)
                    {
                        handler(this, new UpdateOrderChangedEventArgs(oldValue, _updateOrder));
                    }
                }
            }
        }

        public virtual void Initialize()
        {
            if (!IsInitialized)
            {
                SubComponents.Initialize();
                IsInitialized = true;
            }
        }

        public virtual void Update(GameTime gameTime)
        {
            if (Enabled)
            {
                SubComponents.Update(gameTime);
            }
        }

        #endregion

        #region IDisposableEx Members

        public bool IsDisposed { get; protected set; }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}
